/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  server.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2025年04月14日)
 *         Author:  chenhongyu0822@163.com
 *      ChangeLog:  1, Release initial version on "2025年04月14日 11时29分42秒"
 *                 
 ********************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>


void print_usage(char *program)
{
	printf("Usage:%s [OPTION]...\n", program);
	printf("%s is a socket server program\n", program);
	printf(" -b[daemon] set program running on background\n");
	printf(" -p[port] socket server port address\n");
	printf(" -h[help] display this help information\n");
	printf("\nExample:%s -b -p 9000\n", program);
	return;
}

int server_init(char * listen_ip,int listen_port)
{
	int                            rv=0;
	int                            on=1;
	int                            listenfd;
	struct sockaddr_in             seraddr;

	if((listenfd=socket(AF_INET, SOCK_STREAM, 0))<0)
	{
		printf("Use socket() to create a TCP socket failure:%s\n", strerror(errno));
		return -1;
	}

	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	memset(&seraddr, 0, sizeof(seraddr));
	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(listen_port);

	if(!listen_ip)
	{
		seraddr.sin_addr.s_addr=htonl(INADDR_ANY);
	}
	else
	{
		if(inet_pton(AF_INET, listen_ip, &seraddr.sin_addr)<=0)
		{
			printf("inet_pton() set listen ip address failure\n");
			rv=-1;
			goto cleanup;
		}
	}

	if(bind(listenfd, (struct sockaddr *)&seraddr, sizeof(seraddr))<0)
	{
		printf("Use bind() to bind a TCP socket failure:%s\n",strerror(errno));
		rv=-2;
		goto cleanup;
	}

	if(listen(listenfd, 64)<0)
	{
		printf("Use listen() to listen a TCP socket failure:%s\n", strerror(errno));
		rv=-3;
		goto cleanup;
	}
cleanup:
	if(rv<0)
	{
		close(listenfd);
	}
	else
	{
		rv=listenfd;
	}

	return rv;
}


